package com.cndw.kungfu.model.pvp;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.cndw.kungfu.config.ConstantsConfig;
import com.cndw.kungfu.config.ConstantsModel;
import com.cndw.kungfu.domain.Player;
import com.cndw.kungfu.ext.LanguageLib;
import com.cndw.kungfu.ext.LogUtil;
import com.cndw.kungfu.ext.NumberProcesser;
import com.cndw.kungfu.ext.TimeProcesser;
import com.cndw.kungfu.model.Context;
import com.cndw.kungfu.model.DataSerialize;
import com.cndw.kungfu.model.PvpChallengeSerialize;
import com.cndw.kungfu.model.goods.domain.SubPops;
import com.cndw.kungfu.model.goods.domain.SysModeAwards;

/**
 * 
 * 武林大会排行榜
 */
public class ChallengeData implements Serializable {

	private static final long serialVersionUID = 2012116018666620008L;

	private Map<Long, Integer> playerOrderMap = new ConcurrentHashMap<Long, Integer>();

	private transient Map<Integer, Long> orderPlayerMap = new ConcurrentHashMap<Integer, Long>();

	/**
	 * 下次刷新时间
	 */
	private transient volatile int nextAwardTime;

	public int getNextAwardTime() {
		int curTime = TimeProcesser.getUnixTime();
		if (nextAwardTime < curTime) {
			synchronized (this) {
				if (nextAwardTime < curTime) {
					if (nextAwardTime == 0) {
						nextAwardTime = ConstantsConfig.getChallengeBeginTime();
					}
					if (nextAwardTime < curTime) {
						nextAwardTime += NumberProcesser.ceil(curTime - nextAwardTime, ConstantsModel.challengeRefreash) * ConstantsModel.challengeRefreash;
					}
					sync(false);
				}
			}
		}
		return nextAwardTime;
	}

/*	public int getStartTime() {
		//int curTime = TimeProcesser.getUnixTime();
		//int times = NumberProcesser.floor((curTime - ConstantsConfig.getChallengeBeginTime()), ConstantsModel.challengeRefreash);

		int leaveTimes = NumberProcesser.ceil((ConstantsConfig.getSysCgOpenTime() - ConstantsConfig.getChallengeBeginTime()), ConstantsModel.challengeRefreash);
		leaveTimes = leaveTimes <= 0 ? 0 : leaveTimes;
		return ConstantsConfig.getChallengeBeginTime() + leaveTimes * ConstantsModel.challengeRefreash;
		// System.out.println(times + "--" + leaveTimes + "---" +
		// TimeProcesser.getDateByUnixTime(ConstantsConfig.getChallengeBeginTime()
		// + leaveTimes * ConstantsModel.challengeRefreash));
	}*/

	public synchronized int addOrder(long playerId) {
		int currentOrder = orderPlayerMap.size() + 1;
		playerOrderMap.put(playerId, currentOrder);
		orderPlayerMap.put(currentOrder, playerId);
		sync(false);
		return currentOrder;
	}

	public void sync(boolean sync) {
		if (sync || NumberProcesser.isWinning(30)) {
			DataSerialize.getInstance().commitSync();
			PvpChallengeSerialize.getInstance().commitSync();
		}
	}

	public void changeOrder(long sourceId, long targetId) {
		int sourceOrder = playerOrderMap.get(sourceId);
		int targetOrder = playerOrderMap.get(targetId);

		playerOrderMap.put(sourceId, targetOrder);
		playerOrderMap.put(targetId, sourceOrder);
		orderPlayerMap.put(sourceOrder, targetId);
		orderPlayerMap.put(targetOrder, sourceId);
		sync(false);
	}

	public int getOrder(long playerId) {
		if (!playerOrderMap.containsKey(playerId)) {
			return 0;
		}
		return playerOrderMap.get(playerId);
	}

	public long getPlayer(int orderId) {
		if (!orderPlayerMap.containsKey(orderId)) {
			return 0;
		}
		return orderPlayerMap.get(orderId);
	}

	public int getLastRanking(){
		return orderPlayerMap.size();
	}
	
	/**
	 * 获取排行榜
	 * 
	 * @param rankingOffset
	 * @param length
	 * @return
	 */
	public List<Long> getPlayers(int rankingOffset, int length) {
		List<Long> list = new LinkedList<Long>();
		for (int i = rankingOffset; i < rankingOffset + length; i++) {
			long playerId = getPlayer(i);
			if (playerId != 0) {
				list.add(playerId);
			}
		}
		return list;
	}

	/**
	 * 刷新排行奖励
	 */
	public void refreashAward() {
		Runnable r = new Runnable() {
			@Override
			public void run() {
				try {
					if (!(TimeProcesser.inTimePeriod(ConstantsModel.challengeForbidBegin, 86400) || TimeProcesser.inTimePeriod(0,
							ConstantsModel.challengeForbidEnd))) {
						LogUtil.getMain().warn("Challenge data timer run at a unexpected time");
					}
					if (TimeProcesser.inTimePeriod(ConstantsModel.challengeForbidBegin, 86400)) {
						int interval = TimeProcesser.getUnixTime() - TimeProcesser.getMorningTime() - ConstantsModel.challengeForbidBegin;
						if (interval > 0) {
							Thread.sleep(86400 - ConstantsModel.challengeForbidBegin - interval);
						}
						LogUtil.getMain().warn("Challenge data timer run early");
					}
					for (int i = 1; i <= ConstantsModel.challengeRankingAwardNum  && i <= orderPlayerMap.size(); i++) {
						try {
							if(orderPlayerMap.containsKey(i)){
								Long playerId = orderPlayerMap.get(i);
								Player player = Context.getPlayerServer().getByPlayerId(playerId);
								if (player == null) {
									LogUtil.getMain().error("pvp err playerId "+playerId);
									continue;
								}
								int awardsId = 140000 + (i - 1) * 10;
								if(i <= 5){
									awardsId += (player.getLevel() > 100 ? 100 : player.getLevel()) / 10 - 1;//100级以上给100级的奖励
								}
								SysModeAwards sysAwards = SysModeAwards.get(awardsId); 
								if (sysAwards == null) {
									LogUtil.getMain().error("pvp err award "+awardsId);
									continue;
								}
								List<SubPops> currentPops = new ArrayList<SubPops>();
								for (SubPops ep : sysAwards.getSubPopsList()) {
									if(ep.getRantGoodsIds()!= null){
										currentPops.add(ep.copyByRandConfig());
									}else{
										currentPops.add(ep);
									} 
								}
								Context.getMessageServer().sendSysMail(player.getPlayerId(), player.getPlayerName(), LanguageLib.get("pvp.award.title"), LanguageLib.get("pvp.award.content", i, sysAwards.getTitle()), currentPops);
							}
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		};

		Context.getTimerServer().scheduleAtFixedRate(r, getNextAwardTime() - TimeProcesser.getUnixTime() , ConstantsModel.challengeRefreash);
	}

	public void check() {
		if(playerOrderMap == null){
			playerOrderMap = new ConcurrentHashMap<Long, Integer>();
		}
		if(orderPlayerMap == null){
			orderPlayerMap = new ConcurrentHashMap<Integer, Long>();
		}
	}

	public void checkOrderMap() {
		if (orderPlayerMap == null){
			synchronized (ChallengeData.class) {
				if (orderPlayerMap== null) {
					Map<Integer, Long> tmpMap = new ConcurrentHashMap<Integer, Long>();
					for (Map.Entry<Long, Integer> pEntry : playerOrderMap.entrySet()) {
						tmpMap.put(pEntry.getValue(), pEntry.getKey());
					}
					orderPlayerMap = tmpMap;
				}
			}
		}
	
	}
}
